﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Threading;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using PEMS.Common;

namespace PEMS.Server
{
    /// <summary>
    /// PemsService szervíz interfész, funkciók listája
    /// </summary>
    [ServiceContract(SessionMode = SessionMode.Required)]
    public interface IPemsService
    {
        /// <summary>
        /// authentikáció, fogad egy kliens leírót, megvizsgálja, beleír és visszaadja
        /// </summary>
        /// <param name="klid">fogad egy kliens leírót</param>
        /// <returns>visszaad egy kliens leírót</returns>
        [OperationContract(IsInitiating = true)]
        N_FelhasznaloTipus auth(N_FelhasznaloTipus komm);

        /// <summary>
        /// kliens leáll
        /// </summary>
        [OperationContract(IsTerminating = true, IsOneWay=true)]
        void stop();

        /// <summary>
        /// session fenntartása
        /// </summary>
        [OperationContract]
        void ping();

        /// <summary>
        /// a kliens lekérdezi a féléveket / összeset illetve csak azokat amikre jelentkezni lehet
        /// </summary>
        [OperationContract]
        N_1 getFelevLista(N_1 komm);

        /// <summary>
        /// félév hozzáadása
        /// </summary>
        [OperationContract]
        N_Datum felevHozzaadasa(N_Datum komm);

        /// <summary>
        /// felhasználó hozzáadása
        /// </summary>
        [OperationContract]
        N_FelhasznaloTipus felhasznaloHozzaadasa(N_FelhasznaloTipus komm);

        /// <summary>
        /// új tárgy hozzáadása
        /// </summary>
        [OperationContract]
        N_1 targyHozzaadasa(N_1 komm);

        /// <summary>
        /// kurzus meghirdetése
        /// </summary>
        [OperationContract]
        N_1 kurzusMeghirdetese(N_1 komm);

        /// <summary>
        /// vizsga meghirdetése
        /// </summary>
        [OperationContract]
        N_Datum vizsgaMeghirdetese(N_Datum komm);

        /// <summary>
        /// a kliens akarja látni egy félévhez meghirdetett kurzusokat
        /// </summary>
        [OperationContract]
        N_1 getTargyList(N_1 komm);

        /// <summary>
        /// a kliens akarja látni egy félévhez meghirdetett kurzusokat
        /// </summary>
        [OperationContract]
        N_1 getKurzusList(N_1 komm);

        /// <summary>
        /// beiratkozás félévre
        /// </summary>
        [OperationContract]
        N_1 beiratkozasFelevre(N_1 komm);

        /// <summary>
        /// lekérdezi a hallgató félév információit
        /// </summary>
        [OperationContract]
        N_1 getFelevInfo(N_1 komm);

        /// <summary>
        /// lekérdezi, hogy a hallgató beiratkozott-e a félévre
        /// </summary>
        [OperationContract]
        N_1 getFelevFelveve(N_1 komm);

        /// <summary>
        /// lekérdezi, hogy a hallgató felvette-e a kurzust
        /// </summary>
        [OperationContract]
        N_1 getKurzusFelveve(N_1 komm);

        /// <summary>
        /// lekérdezi, hogy a hallgató kapott-e aláírást
        /// </summary>
        [OperationContract]
        N_1 getAlairasBeallitva(N_1 komm);
                
        /// <summary>
        /// a kliens egy félév egy kurzusára feliratokozik
        /// </summary>
        [OperationContract]
        N_1 kurzusraFeliratkozik(N_1 komm);

        /// <summary>
        /// a kliens akarja látni egy félév vizsgaidőpontjait
        /// </summary>
        [OperationContract]
        N_1 getVizsgaIdopontList(N_1 komm);

        /// <summary>
        /// a kliens akarja látni egy félévhez egy kurzusának vizsgaidőpontjait
        /// </summary>
        [OperationContract]
        N_1 getKurzusVizsgaIdopontList(N_1 komm);

        /// <summary>
        /// a kliens akarja látni egy félévhez egy kurzusának vizsgaidőpontjait
        /// </summary>
        [OperationContract]
        N_1 getKurzusbyVizsgaidopontID(N_1 komm);
        
        /// <summary>
        /// vizsgajelentkezés
        /// </summary>
        [OperationContract]
        N_1 vizsgaIdopontraFeliratkozas(N_1 komm);

        /// <summary>
        /// vizsgajegy beírása
        /// </summary>
        [OperationContract]
        N_VizsgaJegyBeiras vizsgajegyBeiras(N_VizsgaJegyBeiras komm);

        /// <summary>
        /// vizsgajegy ellenorzese
        /// </summary>
        [OperationContract]
        N_1 vizsgajegyEllenorzes(N_1 komm);

        /// <summary>
        /// vizsgaeredmények lekérdezése
        /// </summary>
        [OperationContract]
        N_1 getVizsgaEredmenyek(N_1 komm);

        /// <summary>
        /// felvett kurzusok lekérdezése
        /// </summary>
        [OperationContract]
        N_1 getFelvettKurzus(N_1 komm);

        /// <summary>
        /// felvett vizsgák lekérdezése
        /// </summary>
        [OperationContract]
        N_1 getFelvettVizsga(N_1 komm);

        /// <summary>
        /// aláírás beállítása
        /// </summary>
        [OperationContract]
        N_AlairasBeallitas alairasBeallitas(N_AlairasBeallitas komm);

        /// <summary>
        /// Felhasználók listája
        /// </summary>
        [OperationContract]
        N_FelhasznaloTipus getFelhasznaloLista(N_FelhasznaloTipus komm);

        /// <summary>
        /// Felhasználói jogosultság lekérdezése
        /// </summary>
        [OperationContract]
        N_FelhasznaloTipus getFelhasznaloJogosultsag(N_FelhasznaloTipus komm);
                
        /// <summary>
        /// Félév ellenőrzése
        /// </summary>
        [OperationContract]
        N_1 felevLetezik(N_1 komm);

        /// <summary>
        /// Tárgy ellenőrzése
        /// </summary>
        [OperationContract]
        N_1 targyLetezik(N_1 komm);
        
        /// <summary>
        /// Kurzus ellenőrzése
        /// </summary>
        [OperationContract]
        N_1 kurzusLetezik(N_1 komm);

        /// <summary>
        /// Vizsga ellenőrzése
        /// </summary>
        [OperationContract]
        N_1 vizsgaLetezik(N_1 komm);

        /// <summary>
        /// Hallgató ellenőrzése
        /// </summary>
        [OperationContract]
        N_1 felhasznaloLetezik(N_1 komm);
        
        /// <summary>
        /// Aktuális félév lekérdezése
        /// </summary>
        [OperationContract]
        N_1 getAktualisFelev(N_1 komm);
        
    }

    /// <summary>
    /// a szolgáltatás megvalósítója, aki a implementál IPemsService interfészt
    /// ez szolgál kontrollerként
    /// </summary>
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
    public class PemsService : IPemsService
    {
        string user=null;

        /// <summary>
        /// konstruktor
        /// </summary>
        public PemsService()
        {
            Log.logToFile("Szerviz objektum letrehozva (id):   " + this.GetHashCode().ToString(),false);
        }

        /// <summary>
        /// destruktor
        /// </summary>
        ~PemsService()
        {
            Log.logToFile("Szerviz objektum megsemmisitve (id): " + this.GetHashCode().ToString(),false);
            Intezmeny.instance.authenticated.Remove(this.GetHashCode().ToString());
        }

        /// <summary>
        /// kliens lelép
        /// </summary>
        public void stop(){}

        /// <summary>
        /// session fenntartása
        /// </summary>
        public void ping(){}

        /// <summary>
        /// egy felhasználó használhatja-e a rendszert?
        /// </summary>
        /// <param name="komm">őt vizsgáljuk</param>
        /// <returns>visszaadjuk azt amit ő küldött, plusz még beleteszünk infót</returns>
        public N_FelhasznaloTipus auth(N_FelhasznaloTipus komm)
        {
            komm.bools["belepve"] = false;
            komm.msg.Clear();

            lock (Intezmeny._lock)
            {
                foreach (KeyValuePair<string, Ember> e in Intezmeny.instance.emberek.emberList)
                {
                    if (e.Value.userName == komm.strings["userNev"] && e.Value.password == komm.strings["jelszo"] && e.Value.active)
                    {
                        OperationContext context = OperationContext.Current;

                        MessageProperties messageProperties = context.IncomingMessageProperties;
                        RemoteEndpointMessageProperty endpointProperty =
                            messageProperties[RemoteEndpointMessageProperty.Name]
                            as RemoteEndpointMessageProperty;
                        komm.strings["ip"] = endpointProperty.Address;

                        string clientinfo = string.Format("IP[{0}] port[{1}]", endpointProperty.Address, endpointProperty.Port);
                        Log.logToFile(clientinfo, false);
                        komm.strings["id"] = this.GetHashCode().ToString();
                        Log.logToFile(komm.strings["id"], false);

                        bool loggedon = false;
                        foreach (KeyValuePair<string, Auth> kvp in Intezmeny.instance.authenticated)
                        {
                            if (kvp.Value.username == komm.strings["userNev"])
                                loggedon = true;
                        }
                        if (!loggedon)
                        {
                            komm.bools["belepve"] = true;
                            Auth auth = new Auth();
                            auth.username = komm.strings["userNev"];
                            auth.ip = komm.strings["ip"];
                            Intezmeny.instance.authenticated.Add(this.GetHashCode().ToString(), auth);
                            user = komm.strings["userNev"];
                            if (e.Value.GetType() == typeof(Hallgato))
                            {
                                komm.strings["jogosultsag"] = "Hallgato";
                            }
                            if (e.Value.GetType() == typeof(Oktato))
                            {
                                komm.strings["jogosultsag"] = "Oktato";
                            }
                            if (e.Value.GetType() == typeof(Admin))
                            {
                                komm.strings["jogosultsag"] = "Administrator";
                            }
                        }
                        else
                        {
                            komm.msg.Add("Hiba! Ez a felhasznalo mar be van jelentkezve a szerverre!");
                            return komm;
                        }
                    }
                }
            }
            if (!komm.bools["belepve"])
                komm.msg.Add("\nHiba! Felhasznalo vagy jelszo nem megfelelo!");
            return komm;
        }


        /// <summary>
        /// a kliens lekérdezi a féléveket / összeset illetve csak azokat amikre jelentkezni lehet
        /// </summary>
        /// <param name="komm">ebben kapjuk meg a listázáshoz szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_1 getFelevLista(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                komm.row.Add("Felevek listaja:\n\n");
                string aktualis = "";
                foreach (KeyValuePair<string, Felev> f in Intezmeny.instance.felevek.getFelevLista(komm.bools["aktualis"]))
                {
                    if (f.Value.aktualis)
                    {
                        aktualis = " (aktiv)";
                    }
                    else
                    {
                        aktualis = "";
                    }
                    komm.row.Add("Felev azonositoja: " + f.Value.id + aktualis);
                    komm.row.Add("Felev megnevezese: " + f.Value.megnevezes);
                    komm.row.Add("Felev kezdete: " + f.Value.kezdoDatum.ToString());
                    komm.row.Add("Felev vege: " + f.Value.vegDatum.ToString());
                    komm.row.Add("\n");
                }                
            }
            return komm;
        }

        /// <summary>
        /// félév hozzáadása
        /// id / megnevezés / kezdő dátum / vég dátum
        /// </summary>
        /// <param name="komm">ebben kapjuk meg a listázáshoz szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_Datum felevHozzaadasa(N_Datum komm)
        {
            lock (Intezmeny._lock)
            {
                if (Intezmeny.instance.felevek.felevHozzaadasa(komm.strings["id"], komm.strings["megnevezes"], komm.kezdoDatum, komm.vegDatum))
                {
                    komm.bools["hozzaadva"] = true;
                }
                else
                {
                    komm.bools["hozzaadva"] = false;
                }
            }
            return komm;
        }

        /// <summary>
        /// Intézményi tárgyak listázása
        /// </summary>
        public N_1 getTargyList(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                komm.row.Add("Intezmenyi targyak listaja:\n\n");
                foreach (KeyValuePair<string, Targy> t in Intezmeny.instance.targyak.targyLista())
                {
                    komm.row.Add("Targy azonositoja: " + t.Value.id);
                    komm.row.Add("Targy megnevezese: " + t.Value.megnevezes);
                    komm.row.Add("\n");
                }
            }
            return komm;
        }

        /// <summary>
        /// Felvehető kurzusokat akar látni a hallgató
        /// ehhez meg kell adni a félévet
        /// </summary>
        /// <param name="komm">ebben kapjuk meg a listázáshoz szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_1 getKurzusList(N_1 komm)
        {
            lock (Intezmeny._lock)
            {                
                komm.row.Add("Kurzuslista:\n\n");
                //végigmegyünk a félév kurzusain
                foreach (KeyValuePair<string, Kurzus> k in Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).kurzusList)
                {
                    bool listaba = false;
                    if (komm.strings["userName"] != "")
                    {
                        if (k.Value.oktato.userName == komm.strings["userName"])
                        {
                            listaba = true;
                        }
                    }
                    else
                    {
                        listaba = true;
                    }
                    //és beletesszük a visszatérési objektumba
                    if (listaba)
                    {
                        komm.row.Add("Kurzus kodja: " + k.Value.id);
                        komm.row.Add("Megnevezese: " + k.Value.megnevezes);
                        komm.row.Add("\n");
                    }
                }
            }
            return komm;
        }
        
        /// <summary>
        /// Vizsgaidopontra akar jelentkezni a hallgató
        /// ehhez meg kell adni a félévet
        /// és a kurzusid-t
        /// és a vizsgaidopont ID-it
        /// </summary>
        /// <param name="komm">ebben kapjuk meg a vizsga felvételhez szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_1 vizsgaIdopontraFeliratkozas(N_1 komm)
        {
            lock (Intezmeny._lock)
            {   
                try
                {
                    if (Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getFelevJelentkezes(komm.strings["hallgato"]) == null)
                    {
                        komm.msg.Add("Hiba! Felevtagsag kell a vizsgara jelentkezeshez!");
                        return komm;
                    }
                    if (!Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).kurzusTagja(komm.strings["hallgato"]))
                    {
                        komm.msg.Add("Hiba! Kurzustagsag kell a vizsgara jelentkezeshez!");
                        return komm;
                    }
                    //van-e aláírása a hallgatónak?
                    if (!vanAlairas(ref komm))
                    {
                        komm.msg.Add("Hiba! A hallgatonak nincs alairasa, a vizsga nem veheto fel!");
                        return komm;
                    }
                    //van-e már van ilyen névvel jelentkezés?
                    if (Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).getVizsgaIdopont(komm.strings["vizsgaIdopontID"]).jelentkezettVizsgara(komm.strings["hallgato"]))
                    {
                        komm.msg.Add("Hiba! Mar felvette a vizsgat!");
                        return komm;
                    }

                    Vizsga v = Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).getVizsgaIdopont(komm.strings["vizsgaIdopontID"]).vizsgaJelentkezes(Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).getKurzusTag(komm.strings["hallgato"]));
                    //és a vizsgát a kurzustag is nyilvántartja
                    Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).getKurzusTag(komm.strings["hallgato"]).vizsgak.Add(v);
                    komm.msg.Add("Vizsgajelentkezes megtortent a kovetkezo idopontra: " + Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).getVizsgaIdopont(komm.strings["vizsgaIdopontID"]).idopont.ToString());
                }
                catch
                {
                    komm.msg.Add("Hiba a vizsgajelentkezes kozben!");
                }
            }
            return komm;
        }

        /// <summary>
        /// beiratkozás félévre
        /// ehhez meg kell adni a félévet
        /// és a hallgatót
        /// </summary>
        /// <param name="komm">ebben kapjuk meg a felvételhez szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_1 beiratkozasFelevre(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                if (Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).FelevJelentkezes((Hallgato)Intezmeny.instance.emberek.emberList[komm.strings["hallgato"]]))
                {
                    komm.msg.Add("Beiratkozas a felevre megtortent!");
                }
                else
                {
                    komm.msg.Add("Hiba a felevre torteno beiratkozas kozben!");
                }
            }
            return komm;
        }

        /// <summary>
        /// információ a hallgató által felvett félévekről
        /// ehhez meg kell adni a hallgatót
        /// </summary>
        /// <param name="komm">ebben kapjuk meg a felvételhez szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_1 getFelevInfo(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                komm.row.Add("Informacio a felevekrol:\n\n");
                try
                {
                    foreach (KeyValuePair<string, Felev> f in Intezmeny.instance.felevek.getFelevLista(false))
                    {
                        if (f.Value.beiratkozottFelevre(komm.strings["hallgato"]))
                        {
                            komm.row.Add("Szemeszter: " + f.Value.megnevezes);
                            komm.row.Add("Statusz: " + "Meg nincs implementalva!");
                        }
                    }
                    if (komm.row.Count == 0)
                    {
                        komm.row.Add("Meg nem iratkozott be egyetlen felevre sem!");
                    }
                }
                catch
                {
                    komm.row.Clear();
                    komm.row.Add("Hiba a feleves informaciok lekerdezese kozben!");
                }
            }            
            return komm;
        }

        /// <summary>
        /// lekérdezi, hogy a hallgató felvette-e a kérdéses félévet
        /// ehhez meg kell adni a hallgatót és a félévet
        /// </summary>
        /// <param name="komm">ebben kapjuk meg a felvételhez szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_1 getFelevFelveve(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                try
                {
                    if (!Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).aktualis)
                    {
                        komm.msg.Add("Hiba! A felevre nincs beiratkozasi idoszak!");
                        komm.bools["hiba"] = true;
                    }
                    if (Intezmeny.instance.felevek.getFelev(komm.strings["felev"]) == null)
                    {
                        komm.msg.Add("Hiba! Nincs ilyen felev!");
                        komm.bools["hiba"] = true;
                    }
                    if (Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).jelentkezettList.ContainsKey(komm.strings["hallgato"]))
                    {
                        komm.bools["beiratkozott"] = true;
                        komm.msg.Add("Hiba! A hallgato mar beiratkozott a felevre!");
                    }
                }
                catch
                {
                    komm.msg.Add("Hiba a felevtagsag lekerdezese kozben!");
                    komm.bools["hiba"] = true;
                }
            }
            return komm;
        }

        /// <summary>
        /// lekérdezi, hogy a hallgató felvette-e a kérdéses kurzust
        /// ehhez meg kell adni a hallgatót, a kurzust és a félévet
        /// </summary>
        /// <param name="komm">ebben kapjuk meg a felvételhez szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_1 getKurzusFelveve(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                try
                {
                    if (!Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).jelentkezettList.ContainsKey(komm.strings["hallgato"]))
                    {
                        komm.msg.Add("Hiba! Felevtagsag kell a kurzusra jelentkezeshez!");
                        komm.bools["hiba"] = true;
                    }
                    Intezmeny.instance.felevek.getFelev(komm.strings["felev"]);
                    Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]);
                    if (Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).kurzusTagja(komm.strings["hallgato"]))
                    {
                        komm.msg.Add("Hiba! Mar felvette a kurzust!");
                        komm.bools["hiba"] = true;
                    }
                }
                catch (Exception e)
                {
                    komm.msg.Add("Hiba a kurzustagsag lekerdezese kozben!");
                    komm.bools["hiba"] = true;
                }
            }
            return komm;
        }

        /// <summary>
        /// segéd metódus a getAlairasBeallitva() metódushoz
        /// </summary>
        /// <param name="komm">ebben kapjuk meg a felvételhez szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        private bool vanAlairas(ref N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                try
                {
                    foreach (Alairas a in Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).getKurzusTag(komm.strings["hallgato"]).alairasok)
                    {
                        if (a.alairas.Equals(AlairasEnum.alairva))
                        {
                            return true;
                        }
                    }
                }
                catch
                {
                    komm.msg.Add("Hiba az alairas lekerdezese kozben!");
                    komm.bools["hiba"] = true;
                    return false;
                }
                return false;
            }
        }

        /// <summary>
        /// lekérdezi, hogy a hallgatónak van-e aláírása
        /// ehhez meg kell adni a kurzust, a hallgatót és a félévet
        /// </summary>
        /// <param name="komm">ebben kapjuk meg a felvételhez szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_1 getAlairasBeallitva(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                if (!Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).kurzusTagja(komm.strings["hallgato"]))
                {
                    komm.msg.Add("Hiba! A hallgatonak nincs ilyen kurzusa.");
                    komm.bools["hiba"] = true;
                }
                else
                {
                    if (vanAlairas(ref komm))
                    {
                        komm.msg.Add("Hiba! A hallgato mar kapott alairast!");
                        komm.bools["alairva"] = true;
                    }
                }
            }
            return komm;
        }

        /// <summary>
        /// kurzusra akar feliratkozni a hallgató
        /// ehhez meg kell adni a félévet
        /// és a kurzusid-t
        /// </summary>
        /// <param name="komm">ebben kapjuk meg a felvételhez szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_1 kurzusraFeliratkozik(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                if (Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).kurzusList[komm.strings["kurzus"]].kurzusJelentkezes(Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getFelevJelentkezes(komm.strings["hallgato"])))
                {
                    komm.msg.Add("Kurzusjelentkezes megtortent!");
                }
                else
                {
                    komm.msg.Add("Hiba! A kurzus felvetele nem sikerult!");
                }
            }
            return komm;
        }

        /// <summary>
        /// vizsgaidőpontok lekérdezése félév és kurzus alapján
        /// </summary>
        /// <param name="komm">ebben kapjuk meg a felvételhez szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_1 getVizsgaIdopontList(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                komm.row.Add("Meghirdetett vizsgaidopontok: ");
                foreach (KeyValuePair<string, Kurzus> k in Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzusLista())
                    foreach(KeyValuePair<string, VizsgaIdopont> v in k.Value.getVizsgaIdopontok())
                    {
                        komm.row.Add(v.Value.id.ToString());
                        komm.row.Add(v.Value.idopont.ToString());
                        komm.row.Add(v.Value.maxLetszam.ToString());
                        komm.row.Add("\n");
                    }
            }
            return komm;
        }

        /// <summary>
        /// vizsgaidőpontok lekérdezése félév és kurzus alapján
        /// </summary>
        /// <param name="komm">ebben kapjuk meg a felvételhez szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_1 getKurzusVizsgaIdopontList(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                komm.row.Add("Meghirdetett vizsgaidopontok: ");
                foreach (KeyValuePair<string, VizsgaIdopont> kvp in Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).getVizsgaIdopontok())
                {
                    komm.row.Add(kvp.Value.id.ToString());
                    komm.row.Add(kvp.Value.idopont.ToString());
                    komm.row.Add(kvp.Value.maxLetszam.ToString());
                    komm.row.Add("\n");
                }
            }
            return komm;
        }

        /// <summary>
        /// vizsgaidőpontok lekérdezése félév és kurzus alapján
        /// </summary>
        /// <param name="komm">ebben kapjuk meg a felvételhez szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_1 getKurzusbyVizsgaidopontID(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                foreach (KeyValuePair<string, Kurzus> k in Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzusLista())
                    foreach(KeyValuePair<string, VizsgaIdopont> v in k.Value.getVizsgaIdopontok())
                    {
                        if (v.Value.id == komm.strings["vizsgaIdopontID"])
                        {
                            komm.strings["kurzus"] = k.Value.id;
                        }
                    }
            }
            return komm;
        }
         
        /// <summary>
        /// Vizsgajegy beírása oktató által
        /// meg kell adni a félévet, kurzust, vizsgaidőpontot, hallgatót, érdemjegyet
        /// </summary>
        /// <param name="komm">ebben kapjuk meg a jegybeíráshoz szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_1 vizsgajegyEllenorzes(N_1 komm)
        {
            lock (Intezmeny._lock)
            {   
                try
                {
                    // megvizsgáljuk jelentkezett-e a hallgató a vizsgára
                    if (!Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).getVizsgaIdopont(komm.strings["vizsgaidopontID"]).jelentkezettVizsgara(komm.strings["hallgato"]))
                    {
                        komm.msg.Add("Hiba! A hallgato nem jelentkezett vizsgara, nem lehet ertekelni!");
                        komm.bools["vizsgaJegyAdhato"] = false;
                    }
                    // ha már kapott jegyet a vizsgára, nem jelentkezhet ugyanarra az időpontra többet (ugyanis a vizsga már biztosan befejeződött)
                    else if (Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).getVizsgaIdopont(komm.strings["vizsgaidopontID"]).getVizsgaEredmeny(komm.strings["hallgato"]) != ErdemjegyEnum.meg_nem_vizsgazott)
                    {
                        komm.msg.Add("Hiba! A vizsga mar elozoleg ertekelve lett, nem tortent modositas!");
                        komm.bools["vizsgaJegyAdhato"] = false;
                    }
                }
                catch
                {
                    komm.msg.Add("Hiba a vizsgajegy ellenorzese kozben!");
                    komm.bools["vizsgaJegyAdhato"] = false;
                }
            }            
            return komm;
        }

        /// <summary>
        /// Vizsgajegy beírása oktató által
        /// meg kell adni a félévet, kurzust, vizsgaidőpontot, hallgatót, érdemjegyet
        /// </summary>
        /// <param name="komm">ebben kapjuk meg a jegybeíráshoz szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_VizsgaJegyBeiras vizsgajegyBeiras(N_VizsgaJegyBeiras komm)
        {
            lock (Intezmeny._lock)
            {                
                try
                {
                    Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).getVizsgaIdopont(komm.strings["vizsgaIdopontID"]).vizsgaErtekelese(komm.strings["hallgato"], komm.erdemjegy);
                    komm.msg.Add("Vizsga ertekelese megtortent! A beirt jegy: " + Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).getVizsgaIdopont(komm.strings["vizsgaIdopontID"]).getVizsgaEredmeny(komm.strings["hallgato"]).ToString());
                }
                catch
                {
                    komm.msg.Add("Hiba a vizsgajegy beirasa kozben!");
                }
            }
            return komm;
        }

        /// <summary>
        /// Felvett kurzusok lekérdezése
        /// meg kell adni a félévet és a hallgatót
        /// </summary>
        /// <param name="komm">ebben kapjuk meg a lekérdezéshez szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_1 getFelvettKurzus(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                foreach (KeyValuePair<string, Kurzus> k in Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).kurzusList)
                    foreach (KeyValuePair<string, KurzusTagsag> kt in k.Value.kurzusTagList)
                        if (kt.Value.felevJelentkezes.hallgato.userName.Equals(komm.strings["hallgato"]))
                        {
                            try
                            {
                                komm.row.Add("Kurzus ID: " + k.Value.id);
                                komm.row.Add("Kurzus megnevezese: " + k.Value.targy.megnevezes);
                                komm.row.Add("Felvetelek szama: " + k.Value.targy.felvetelekSzama[komm.strings["hallgato"]].ToString());
                                komm.row.Add("\n");
                            }
                            catch 
                            {
                                komm.row.Clear();
                                komm.row.Add("Hiba a felvett kurzusok lekerdezese kozben!");
                            }
                        }
            }            
            return komm;
        }

        /// <summary>
        /// Felvett vizsgák lekérdezése
        /// meg kell adni a félévet és a hallgatót
        /// </summary>
        /// <param name="komm">ebben kapjuk meg a lekérdezéshez szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_1 getFelvettVizsga(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                komm.row.Add("Felvett vizsgak:\n\n");
                foreach (KeyValuePair<string, Kurzus> k in Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzusLista())
                    foreach (KeyValuePair<string, VizsgaIdopont> v in k.Value.getVizsgaIdopontok())
                    {
                        bool listaba = false;
                        if (v.Value.jelentkezettVizsgara(komm.strings["hallgato"]))
                        {
                            if (komm.strings["kurzus"] != "")
                            {
                                if (k.Value.id == komm.strings["kurzus"])
                                {
                                    komm.strings["vizsgaidopontID"] = v.Value.id;
                                    return komm;
                                }
                            }
                            else
                            {
                                listaba = true;
                            }                            
                        }
                        if (listaba)
                        {
                            komm.row.Add("Tantargy neve: " + k.Value.targy.megnevezes.ToString());
                            komm.row.Add("Idopont: " + v.Value.idopont.ToString());
                            komm.row.Add("\n");
                        }
                    }
            }
            return komm;
        }

        /// <summary>
        /// Vizsgaeredmények lekérdezése
        /// meg kell adni a félévet és a hallgatót
        /// </summary>
        /// <param name="komm">ebben kapjuk meg a lekérdezéshez szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_1 getVizsgaEredmenyek(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                komm.row.Add("Vizsgaeredmenyek:\n\n");
                foreach (KeyValuePair<string, Kurzus> k in Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzusLista())
                    foreach (KeyValuePair<string,VizsgaIdopont> v in k.Value.getVizsgaIdopontok())
                        if (v.Value.jelentkezettVizsgara(komm.strings["hallgato"]))
                        {
                            komm.row.Add(k.Value.targy.megnevezes.ToString());
                            if (v.Value.getVizsgaEredmeny(komm.strings["hallgato"]) != ErdemjegyEnum.meg_nem_vizsgazott)
                            {
                                komm.row.Add(v.Value.getVizsgaEredmeny(komm.strings["hallgato"]).ToString());
                            }
                            else
                            {
                                komm.row.Add("Meg nincs ertekelve a vizsga.");
                            }
                        }
            }
            return komm;
        }

        /// <summary>
        /// Aláírás beállítása oktató által
        /// meg kell adni a félévet, kurzust, hallgatót
        /// </summary>
        /// <param name="komm">ebben kapjuk meg az aláírásbeállításhoz szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_AlairasBeallitas alairasBeallitas(N_AlairasBeallitas komm)
        {
            lock (Intezmeny._lock)
            {
                try
                {
                    Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).getKurzusTag(komm.strings["hallgato"]).alairasBeallitasa(komm.alairasErtek);
                    komm.msg.Add("Alairas beallitasa sikeres.");
                }
                catch
                {
                    komm.msg.Add("Hiba az alairas beallitasa beirasa kozben!");
                }
            }
            return komm;
        }

        /// <summary>
        /// Felhasználók listája
        /// komm.jogosultság paraméter alapján Oktatók / Hallgatók / Adminok listázása is lehetséges
        /// komm.bools["csakAktiv"] paraméter dönti el, hogy csak az aktív felhasználók kerülnek-e listázásra vagy az összes
        /// </summary>
        /// <param name="komm">ebben kapjuk meg az aláírásbeállításhoz szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_FelhasznaloTipus getFelhasznaloLista(N_FelhasznaloTipus komm)
        {
            lock (Intezmeny._lock)
            {
                if (komm.jogosultsag == UserTypeEnum.oktato)
                {
                    komm.row.Add("Oktatok listaja:\n\n");
                }
                else
                {
                    komm.row.Add("Hallgatok listaja:\n\n");
                }
                foreach (Ember e in Intezmeny.instance.emberek.getFelhasznalok())
                {
                    bool listaba = false;
                    if (e.jogosultsag == komm.jogosultsag)
                    {
                        if (komm.bools["csakAktiv"])
                        {                                                        
                            if (e.active)
                            {
                                if (komm.strings["kurzus"] != "")
                                {
                                    if (komm.strings["vizsgaidopontID"] != "")
                                    {
                                        if (Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).getVizsgaIdopont(komm.strings["vizsgaidopontID"]).jelentkezettVizsgara(e.userName))
                                        {
                                            if (!Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).getVizsgaIdopont(komm.strings["vizsgaidopontID"]).vizsganMegjelent(e.userName))
                                            {
                                                listaba = true;                                            
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).kurzusTagja(e.userName))
                                        {                                            
                                            if (komm.bools["alairasLista"])
                                            {
                                                if (!Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).getKurzusTag(e.userName).kapottAlairast())
                                                {
                                                    listaba = true;
                                                }
                                            }
                                            else
                                            {
                                                foreach (KeyValuePair<string, VizsgaIdopont> v in Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).getVizsgaIdopontok())
                                                {
                                                    if ((!v.Value.vizsganMegjelent(e.userName)) && (Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).getKurzusTag(e.userName).kapottAlairast()))
                                                    {
                                                        listaba = true;
                                                    }
                                                }
                                            }                                            
                                        }
                                    }
                                }
                                else
                                {
                                    listaba = true;
                                }
                            }
                        }
                        else
                        {
                            listaba = true;
                        }
                        if (listaba)
                        {
                            komm.row.Add("ID: " + e.userName);
                            komm.row.Add("Nev: " + e.fullName);
                            if (e.active)
                            {
                                komm.row.Add("Aktiv: " + "Igen");
                            }
                            else
                            {
                                komm.row.Add("Aktiv: " + "Nem");
                            }
                            komm.row.Add("\n");
                        }
                    }
                }
            }
            return komm;
        }

        /// <summary>
        /// Felhasználói jogosultság lekérdezése
        /// userName alapján
        /// </summary>
        /// <param name="komm">ebben kapjuk meg az aláírásbeállításhoz szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_FelhasznaloTipus getFelhasznaloJogosultsag(N_FelhasznaloTipus komm)
        {
            lock (Intezmeny._lock)
            {
                komm.jogosultsag = UserTypeEnum.nincs_ilyen_felhasznalo;
                foreach (Ember e in Intezmeny.instance.emberek.getFelhasznalok())
                {
                    if (e.userName == komm.strings["userName"])
                    {
                        komm.jogosultsag = e.jogosultsag;
                    }
                }
                return komm;
            }
        }
        
        /// <summary>
        /// Félév meglétének ellenőrzése
        /// ehhez meg kell adni a kérdéses félévet
        /// </summary>
        public N_1 felevLetezik(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                if (Intezmeny.instance.felevek.getFelev(komm.strings["felev"]) != null)
                {
                    komm.bools["letezik"] = true;
                }
                return komm;
            }
        }

        /// <summary>
        /// Tárgy meglétének ellenőrzése
        /// ehhez meg kell adni a kérdéses tárgyat
        /// </summary>
        public N_1 targyLetezik(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                if (Intezmeny.instance.targyak.getTargy(komm.strings["targy"]) != null)
                {
                    komm.bools["letezik"] = true;
                }
                return komm;
            }
        }

        /// <summary>
        /// Kurzus meglétének ellenőrzése
        /// ehhez meg kell adni a kérdéses félévet és a kurzust
        /// </summary>
        public N_1 kurzusLetezik(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                try
                {
                    if (Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]) != null)
                    {
                        komm.bools["letezik"] = true;
                    }
                }
                catch
                {
                    return komm;
                }
                return komm;
            }
        }

        /// <summary>
        /// Vizsga meglétének ellenőrzése
        /// ehhez meg kell adni a kérdéses félévet, a kurzust és a vizsgát
        /// </summary>
        public N_1 vizsgaLetezik(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                if (Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).getVizsgaIdopont(komm.strings["vizsga"]) != null)
                {
                    komm.bools["letezik"] = true;
                }
                return komm;
            }
        }

        /// <summary>
        /// Hallgat meglétének ellenőrzése
        /// ehhez meg kell adni a hallgatót
        /// </summary>
        public N_1 felhasznaloLetezik(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                if (Intezmeny.instance.emberek.getFelhasznalo(komm.strings["felhasznalo"]) != null)
                {
                    komm.bools["letezik"] = true;
                }
                return komm;
            }
        }

        /// <summary>
        /// Aktuális félév lekérdezése
        /// </summary>
        /// <param name="komm">ebben kapjuk meg az aláírásbeállításhoz szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_1 getAktualisFelev(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                komm.strings["felev"] = Intezmeny.instance.felevek.getAktualisFelev();
                {
                    komm.bools["letezik"] = true;
                }
                return komm;
            }
        }

        /// <summary>
        /// Felhasználó hozzáadása
        /// </summary>
        /// <param name="komm">ebben kapjuk meg az aláírásbeállításhoz szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_FelhasznaloTipus felhasznaloHozzaadasa(N_FelhasznaloTipus komm)
        {
            lock (Intezmeny._lock)
            {
                try
                {
                    Intezmeny.instance.emberek.felhasznaloHozzaadasa(komm.strings["userName"], komm.strings["fullName"], komm.strings["password"], komm.jogosultsag);
                    komm.bools["hozzaadva"] = true;
                }
                catch
                {
                    komm.bools["hozzaadva"] = false;
                }
                return komm;
            }
        }

        /// <summary>
        /// új tárgy hozzáadása
        /// </summary>
        public N_1 targyHozzaadasa(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                try
                {
                    Intezmeny.instance.targyak.targyHozzaadasa(komm.strings["id"], komm.strings["megnevezes"]);
                    komm.bools["hozzaadva"] = true;
                }
                catch
                {
                    komm.bools["hozzaadva"] = false;
                }
                return komm;
            }
        }

        /// <summary>
        /// Kurzus meghirdetése
        /// </summary>
        /// <param name="komm">ebben kapjuk meg az aláírásbeállításhoz szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_1 kurzusMeghirdetese(N_1 komm)
        {
            lock (Intezmeny._lock)
            {
                Oktato oktato = (Oktato)Intezmeny.instance.emberek.getFelhasznalo(komm.strings["oktato"]);
                Targy targy = Intezmeny.instance.targyak.getTargy(komm.strings["targy"]);
                if (Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).kurzusMeghirdetese(komm.strings["kurzus"], komm.strings["megnevezes"], oktato, targy))
                {
                    komm.bools["hozzaadva"] = true;
                }
                return komm;
            }
        }

        /// <summary>
        /// Vizsga meghirdetése
        /// </summary>
        /// <param name="komm">ebben kapjuk meg az aláírásbeállításhoz szükséges infokat</param>
        /// <returns>visszaadjuk azt amit ő küldött, és beletesszük a visszatérési infot</returns>
        public N_Datum vizsgaMeghirdetese(N_Datum komm)
        {
            lock (Intezmeny._lock)
            {
                if (Intezmeny.instance.felevek.getFelev(komm.strings["felev"]).getKurzus(komm.strings["kurzus"]).vizsgaMeghirdetese(komm.kezdoDatum, komm.ints["maxLetszam"]))
                {
                    komm.bools["hozzaadva"] = true;
                }
                return komm;
            }
        }


        
    }
}
